最主要的雲端資源都建置完成了,在進入程式碼開發之前我們先來確保雲端資源的連接,有兩個部分要進行確認跟設定
開發環境連線至雲端資源
在開發過程中要能夠連接到雲端資源,畢竟不可能每次調整程式都跑一次 CI/CD 部屬到 Cloud Run 上之後再進行應用程式的測試跟驗證。
雲端資源之間的連線
Compute 服務 Cloud Run 能不能順利的連接到其他的雲端資源
我們的應用最主要會連線的雲端元件有 3 個 Cloud SQL、Memory for Redis、Pub/Sub,接下來就分別確認一下開發環境跟 Clour Run 是否能夠連線道以上三個資源
先前建立 Cloud SQL 時是直接將我們的 Public IP 加入到白名單來做連線測試,但如果沒有固定的 IP 每次都要調整白名單是相當麻煩的,如果白名單開太大也會有安全風險 Cloud Sql 提供了一種方式可以從 Local 透過 Porxy 的方式連線到 Cloud Sql
大家可以根據自己的 OS 參考官方文件進行配置 Connect using the Cloud SQL Auth Proxy ,配置完畢之後來測試一下。
先在 Local 測試,首先用 DB 管理工具連線看看 OK 看起來沒問題
再來使用程式連線看看,拿先前部屬至 Cloud Run 的 SalesService 做調整
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
新增一個目錄Data
,在裡面新增一個 TicketSalesContext.cs
內容如下
using Microsoft.EntityFrameworkCore;
namespace iThome2024.SalesService.Data;
public class TicketSalesContext : DbContext
{
public TicketSalesContext(DbContextOptions<TicketSalesContext> options) : base(options)
{
}
}
using iThome2024.SalesService.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddDbContext<TicketSalesContext>(options =>
{
options.UseNpgsql(builder.Configuration.GetConnectionString("TicketSalesContext"));
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapGet("/TestDbConnection", (TicketSalesContext context) =>
{
return context.Database.CanConnect();
})
.WithName("TestDbConnection")
.WithOpenApi(); ;
app.Run();
appsettings.Development.json
填寫連線字串,Password 記得換成你的 db 密碼{
"ConnectionStrings": {
"TicketSalesContext": "Host=localhost; Database=postgres; Username=postgres; Password=mypassword"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
調整完畢之後來測試一下 OK
在 Proxy 的視窗也可以看到連線的紀錄
在 Local 測試完成後可以推到 Cloud Run 上進行測試,先前已將 CI/CD Pipeline 建立好了,這裡只要推一個Commit 到 main 的分支 Cloud Build 就會自動進行 CI/CD 了。
等 Cloud Run 重新佈署完畢,來試打看看
可以看到 Cloud Run 毫不留情的吐了一個 False,資料庫在 Cloud Run 上並沒有成功連線,是為什麼呢?
剛剛的連線字串是寫在appsettings.Development.json
是屬於開發環境的 setting,部屬上去當然就會取不到連線字串,你會想那直接寫在appsettings.json
不就好了,這是可行但不推薦的,把連線字串存放在應用程式內部是個不明智的選擇,那我們可以怎麼做,Cloud Run 是可以設定環境變數的,我們來試試看。
在 Cloud Run 的編輯畫面找到設定環境變數的地方,建立一個新的環境變數 ConnectionString__TicketSalesContext
.NET 的 Configaton Service 如果在 appsetting 取不到對應的值是會往外由環境變數取的,要用__
來替換 json 階層的:
如連線字串是ConnectionStrings:TicketSalesContext
就要替換成ConnectionString__TicketSalesContext
,Configaton Service 會自動解析並取出對應的值
這裡要注意 Host 要改成/cloudsql/[連線名稱]
這種格式會使用 Unix socket 進行連線,詳細的說明可以參考 Connect from Cloud Run
再測試一次,可以看到就打的通了。
可以透過設定環境變數來給予 Cloud Run 連線字串,但實際上環境變數也是明文存放在 Cloud Run 的 yaml ,可以在 Console 上看到
Cloud Run 的環境變數是可以跟 Google Cloud 的另外一個安全性的服務 Secret Manager 連結他會將資料加密後儲存,只有在應用啟動時去取用並解密出來,這個部分我們明天再繼續說明